# 1,逻辑和代码大幅重构
#
#
#

from tqsdk import TqApi, TqAccount, TqSim, TargetPosTask
from tqsdk.ta import BOLL
import os, time, math, sqlite3
from apscheduler.schedulers.background import BackgroundScheduler
import configparser
from myfun import * 


#读取配置文件
cp = configparser.ConfigParser()
cp.read("config.conf",encoding="utf-8")
#读取账户信息
cp_broker_id = cp.get('default', 'broker_id')
cp_account_id = cp.get('default', 'account_id')
cp_password = cp.get('default', 'password')


#基于Boll指标的开仓、设止损、平保、错单处理函数
#--------------------------------------Api 主函数--------------------------------------
def order_by_boll(symbol, gsd, gpd, period, margin, trade_count):
    # 创建API实例
    api = TqApi(TqAccount(cp_broker_id, cp_account_id, cp_password),web_gui=False)
    # 获取交易品种信息、账户信息
    quote = api.get_quote(symbol)
    account = api.get_account()
    position = api.get_position(symbol)
    #print(position)
    target_pos = TargetPosTask(api, symbol)
    #获取K线信息
    klines = api.get_kline_serial(symbol,period * 60)  #24 * 60 * 60 日线，5*60，5分钟K线
    #计算boll的值
    boll = BOLL(klines, 26, 12)
    #在web_gui中画出mid的值
    klines["boll_stp"] = boll["mid"] #BOLL中轨MID实际就是MA26
    klines["boll_stp.color"] = 0xff0000ff  #绿色：0xFF00FF00，蓝色：0xff0000ff
    #---自定义变量---
    #循环变量
    loop = 0
    #持仓止损阶段，分为三个阶段，①，初次建仓固定点数止损，如：10点，②当涨跌N点后，设置平仓保护，③当持有多单（空单）且均线值在三个止损值种最大（小）时以均线止损
    g_flag_long = 0
    g_flag_short = 0
    #初次止损价差，即：第一级止损位和开仓价的价差,注意乘以最小变动价位，quote.price_tick
    # print("------------------调试----------------------")
    # print("gsd",gsd)
    # print("quote.price_tick:",quote.price_tick)
    g_stp_diff = gsd*quote.price_tick
    # print("g_stp_diff:",g_stp_diff)
    # print("------------------调试----------------------")
    #止损价
    g_stp_long = 0
    g_stp_short = 0
    #平仓保护价差
    g_pb_diff = gpd*quote.price_tick
    #多空持仓量前值
    g_pre_pos_long = 0
    g_pre_pos_short = 0
    #允许开仓几次
    g_trade_count = 0
    #下单量
    g_lots=0
    #多空开关
    g_long_enabled=True #True允许做多，False不允许做多
    g_short_enabled=True
    #为确保能及时成交，下单时追几个价位
    g_price_diff=2*quote.price_tick
    #存储订单号
    #空单
    g_order_kk=[] #空头开仓订单
    g_order_kp=[] #空头平仓订单
    g_order_ks=[] #空头止损
    g_order_kc=[] #空头错单
    #多单
    g_order_dk=[] #多头开仓
    g_order_dp=[] #多头平仓
    g_order_ds=[] #空头止损
    g_order_dc=[] #多头错单
    #平昨平今
    #错单
    g_order_dcpz=[]#多措平昨
    g_order_dcpj=[]#多措平今
    g_order_kcpz=[]#空措平昨
    g_order_kcpj=[]#空措平昨
    #损单
    g_order_dspz=[]#多损平昨
    g_order_dspj=[]#多损平今
    g_order_kspz=[]#空损平昨
    g_order_kspj=[]#空损平昨

    #建立个函数，初始化全局变量
    def g_init():
        g_flag_long = 0 # 用来在持有多单时，控制初始止损、平保、移动止损，在没有多单、多单平仓之后，该变量应该初始化为0
        g_flag_short = 0
        g_pre_pos_long = 0 # 用来记录前一持仓的持仓量
        g_pre_pos_short = 0

    while True:
        # 调用 wait_update 等待业务信息发生变化，例如: 行情发生变化, 委托单状态变化, 发生成交等等
        # 注意：其他合约的行情的更新也会触发业务信息变化，因此这里可能会将同一笔行情输出多次
        #异常处理
        try:
            api.wait_update()

            #移动平均线前值，即止损值
            #boll = BOLL(klines, 26, 12) #是否需要在wait_update()后，重新计算boll的值，有争议，在这里试一试
            boll = BOLL(klines, 26, 12)
            pre_boll_value = round(boll["mid"].iloc[-2], 5)
            g_stp_long=quote.bid_price1-g_stp_diff   # pre_boll_value-g_stp_diff
            g_stp_short=quote.ask_price1+g_stp_diff   # pre_boll_value+g_stp_diff
            #计算开仓量，注意计算公式可根据自己需要调整
            g_lots=math.floor((account.available*0.2/margin)*0.8)

            #对订单进行处理
            #开多成交
            if g_order_dk and api.is_changing(g_order_dk[-1], ["status", "volume_orign", "volume_left"]): #and g_order_dk[-1]["last_msg"]=="全部成交报单已提交"
                if g_order_dk[-1].status=="FINISHED" and g_order_dk[-1].volume_orign>=0 and g_order_dk[-1].volume_left>=0:
                    flots=(g_order_dk[-1].volume_orign - g_order_dk[-1].volume_left)
                    price=g_order_dk[-1].trade_price
                    time=g_order_dk[-1].insert_date_time
                    insert_orders_table(symbol,"BUY","OPEN",flots,price,time,"nan","多头开仓")
                    print("多头开仓： ",flots)
            # #平多成交
            # if g_order_dp[-1].status=="FINISHED":
            #     flots=(g_order_dp[-1].volume_orign - g_orders[-1].volume_left)
            #     price=g_order_dp[-1].trade_price
            #     time=g_order_dp[-1].insert_date_time
            #     insert_orders_table(symbol,"SELL","CLOSE",flots,price,time,"nan","多头平仓")
            #     print("平多成交： ",flots)
            #开空成交
            if g_order_kk and api.is_changing(g_order_kk[-1], ["status", "volume_orign", "volume_left"]): #and g_order_kk[-1]["last_msg"]=="全部成交报单已提交"
                if g_order_kk[-1].status=="FINISHED" and g_order_kk[-1].volume_orign>=0 and g_order_kk[-1].volume_left>=0:
                    flots=(g_order_kk[-1].volume_orign - g_order_kk[-1].volume_left)
                    price=g_order_kk[-1].trade_price
                    time=g_order_kk[-1].insert_date_time
                    insert_orders_table(symbol,"SELL","OPEN",flots,price,time,"nan","空头开仓")
                    print("空头开仓： ",flots," 开仓价格： ",price)
            # #空平成交
            # if g_order_kp[-1].status=="FINISHED":
            #     flots=(g_order_kp[-1].volume_orign - g_orders[-1].volume_left)
            #     price=g_order_kp[-1].trade_price
            #     time=g_order_kp[-1].insert_date_time
            #     insert_orders_table(symbol,"BUY","CLOSE",flots,price,time,"nan","空头开仓")
            #     print("平空成交： ",flots)
            #多头错单处理
            if g_order_dc and api.is_changing(g_order_dc[-1], ["status", "volume_orign", "volume_left"]): #and g_order_dc[-1]["last_msg"]=="全部成交报单已提交"
                if g_order_dc[-1].status=="FINISHED" and g_order_dc[-1].volume_orign>=0 and g_order_dc[-1].volume_left>=0:
                    flots=(g_order_dc[-1].volume_orign - g_order_dc[-1].volume_left)
                    price=g_order_dc[-1].trade_price
                    time=g_order_dc[-1].insert_date_time
                    insert_orders_table(symbol,"SELL","CLOSE",flots,price,time,"nan","多措平仓")
                    print("多措平仓： ",flots," 开仓价格： ",price)
            #多措平昨
            if g_order_dcpz and api.is_changing(g_order_dcpz[-1], ["status", "volume_orign", "volume_left"]): #and g_order_kcpz[-1]["last_msg"]=="全部成交报单已提交" 
                if g_order_dcpz[-1].status=="FINISHED" and g_order_dcpz[-1].volume_orign>=0 and g_order_dcpz[-1].volume_left>=0:
                    flots=(g_order_dcpz[-1].volume_orign - g_order_dcpz[-1].volume_left)
                    price=g_order_dcpz[-1].trade_price
                    time=g_order_dcpz[-1].insert_date_time
                    insert_orders_table(symbol,"SELL","CLOSE",flots,price,time,"nan","多措平昨")
                    print("多措平昨： ",flots)
            #多措平今
            if g_order_dcpj and api.is_changing(g_order_dcpj[-1], ["status", "volume_orign", "volume_left"]): # and g_order_dcpj[-1]["last_msg"]=="全部成交报单已提交"
                if g_order_dcpj[-1].status=="FINISHED" and g_order_dcpj[-1].volume_orign>=0 and g_order_dcpj[-1].volume_left>=0:
                    flots=(g_order_dcpj[-1].volume_orign - g_order_dcpj[-1].volume_left)
                    price=g_order_dcpj[-1].trade_price
                    time=g_order_dcpj[-1].insert_date_time
                    insert_orders_table(symbol,"SELL","CLOSE",flots,price,time,"nan","多措平今")
                    print("多措平今： ",flots)
            #空头错单处理
            #if g_order_kc:print(g_order_kc)
            if g_order_kc and api.is_changing(g_order_kc[-1], ["status", "volume_orign", "volume_left"]): #and g_order_kc[-1]["last_msg"]=="全部成交报单已提交"
                if g_order_kc[-1].status=="FINISHED" and g_order_kc[-1].volume_orign>=0 and g_order_kc[-1].volume_left>=0:
                    flots=(g_order_kc[-1].volume_orign - g_order_kc[-1].volume_left)
                    price=g_order_kc[-1].trade_price
                    time=g_order_kc[-1].insert_date_time
                    insert_orders_table(symbol,"BUY","CLOSE",flots,price,time,"nan","空错平仓")
                    print("空错平仓： ",flots)
            #空错平昨
            if g_order_kcpz and api.is_changing(g_order_kcpz[-1], ["status", "volume_orign", "volume_left"]): #and g_order_kcpz[-1]["last_msg"]=="全部成交报单已提交" 
                if g_order_kcpz[-1].status=="FINISHED" and g_order_kcpz[-1].volume_orign>=0 and g_order_kcpz[-1].volume_left>=0:
                    flots=(g_order_kcpz[-1].volume_orign - g_order_kcpz[-1].volume_left)
                    price=g_order_kcpz[-1].trade_price
                    time=g_order_kcpz[-1].insert_date_time
                    insert_orders_table(symbol,"BUY","CLOSE",flots,price,time,"nan","空错平昨")
                    print("空错平昨： ",flots)
            #空错平今
            if g_order_kcpj and api.is_changing(g_order_kcpj[-1], ["status", "volume_orign", "volume_left"]): #and g_order_kcpj[-1]["last_msg"]=="全部成交报单已提交" 
                if g_order_kcpj[-1].status=="FINISHED" and g_order_kcpj[-1].volume_orign>=0 and g_order_kcpj[-1].volume_left>=0:
                    flots=(g_order_kcpj[-1].volume_orign - g_order_kcpj[-1].volume_left)
                    price=g_order_kcpj[-1].trade_price
                    time=g_order_kcpj[-1].insert_date_time
                    insert_orders_table(symbol,"BUY","CLOSE",flots,price,time,"nan","空错平今")
                    print("空错平今： ",flots)
            #多头止损
            if g_order_ds and api.is_changing(g_order_ds[-1], ["status", "volume_orign", "volume_left"]): #and g_order_ds[-1]["last_msg"]=="全部成交报单已提交"
                if g_order_ds[-1].status=="FINISHED" and g_order_ds[-1].volume_orign>=0 and g_order_ds[-1].volume_left>=0:
                    flots=(g_order_ds[-1].volume_orign - g_order_ds[-1].volume_left)
                    price=g_order_ds[-1].trade_price
                    time=g_order_ds[-1].insert_date_time
                    insert_orders_table(symbol,"SELL","CLOSE",flots,price,time,"nan","多头止损")
                    print("多头止损： ",flots)
            #多头止损,平昨
            if g_order_dspz and api.is_changing(g_order_dspz[-1], ["status", "volume_orign", "volume_left"]): # and g_order_dspz[-1]["last_msg"]=="全部成交报单已提交"
                if g_order_dspz[-1].status=="FINISHED" and g_order_dspz[-1].volume_orign>=0 and g_order_dspz[-1].volume_left>=0:
                    flots=(g_order_dspz[-1].volume_orign - g_order_dspz[-1].volume_left)
                    price=g_order_dspz[-1].trade_price
                    time=g_order_dspz[-1].insert_date_time
                    insert_orders_table(symbol,"SELL","CLOSE",flots,price,time,"nan","多损平昨")
                    print("多损平昨： ",flots)
            #多头止损,平今
            if g_order_dspj and api.is_changing(g_order_dspj[-1], ["status", "volume_orign", "volume_left"]): # and g_order_dspj[-1]["last_msg"]=="全部成交报单已提交"
                if g_order_dspj[-1].status=="FINISHED" and g_order_dspj[-1].volume_orign>=0 and g_order_dspj[-1].volume_left>=0:
                    flots=(g_order_dspj[-1].volume_orign - g_order_dspj[-1].volume_left)
                    price=g_order_dspj[-1].trade_price
                    time=g_order_dspj[-1].insert_date_time
                    insert_orders_table(symbol,"SELL","CLOSE",flots,price,time,"nan","多损平今")
                    print("多损平今 ",flots)
            #空头止损
            if g_order_ks and api.is_changing(g_order_ks[-1], ["status", "volume_orign", "volume_left"]): #and g_order_ks[-1]["last_msg"]=="全部成交报单已提交"
                if g_order_ks[-1].status=="FINISHED" and g_order_ks[-1].volume_orign>=0 and g_order_ks[-1].volume_left>=0:
                    flots=(g_order_ks[-1].volume_orign - g_order_ks[-1].volume_left)
                    price=g_order_ks[-1].trade_price
                    time=g_order_ks[-1].insert_date_time
                    insert_orders_table(symbol,"BUY","CLOSE",flots,price,time,"nan","空头止损")
                    print("空头止损： ",flots)
            #空头止损，平昨
            if g_order_kspz and api.is_changing(g_order_kspz[-1], ["status", "volume_orign", "volume_left"]): # and g_order_kspz[-1]["last_msg"]=="全部成交报单已提交"
                if g_order_kspz[-1].status=="FINISHED" and g_order_kspz[-1].volume_orign>=0 and g_order_kspz[-1].volume_left>=0:
                    flots=(g_order_kspz[-1].volume_orign - g_order_kspz[-1].volume_left)
                    price=g_order_kspz[-1].trade_price
                    time=g_order_kspz[-1].insert_date_time
                    insert_orders_table(symbol,"BUY","CLOSE",flots,price,time,"nan","空损平昨")
                    print("空头止损平昨 ",flots)
            #空头止损，平今
            if g_order_kspj and api.is_changing(g_order_kspj[-1], ["status", "volume_orign", "volume_left"]): # and g_order_kspj[-1]["last_msg"]=="全部成交报单已提交"
                if g_order_kspj[-1].status=="FINISHED" and g_order_kspj[-1].volume_orign>=0 and g_order_kspj[-1].volume_left>=0:
                    flots=(g_order_kspj[-1].volume_orign - g_order_kspj[-1].volume_left)
                    price=g_order_kspj[-1].trade_price
                    time=g_order_kspj[-1].insert_date_time
                    insert_orders_table(symbol,"BUY","CLOSE",flots,price,time,"nan","空损平今")
                    print("空损平今 ",flots)

            # #挂单，超过一分钟，撤单
            # if g_order_dk and g_order_dk[-1].status=""ALIVE and :
            #     pass


            #净持仓发生变化时，输出账户相关信息,该信息可自行修改
            if api.is_changing(position, ["pos_long_his", "pos_long_today", "pos_short_his","pos_short_today"]):
                log_time = "轮询次数：", loop, "时间：", quote.datetime
                log_info=symbol+"  最新价：",quote.last_price,"账户权益：",round(account.balance,2),"多单持仓量：",position.pos_long,\
                    "多单持仓均价：",position.position_price_long,"空单持仓量：",position.pos_short,"空单持仓均价：",\
                    position.position_price_short,"止损均线值：",pre_boll_value
                #print(log_time,"\n",log_info,"\n")
                #将账户信息存入日志
                write_log(log_time,log_info)
                #持仓发生变化后，初始化涉及止损的几个全局变量，以进行止损等操作
                # if position.pos_long == 0 and position.pos_short == 0 and (g_flag_long!=0 or g_flag_short!=0 or g_pre_pos_long!=0 or g_pre_pos_short!=0):
                #     g_init()
                #持仓发生变化后输出账户持仓信息：
                if position.pos_long>0:
                    print("代码", symbol, "时间：", quote.datetime, "多单持仓量：",position.pos_long, "多单持仓均价：",position.open_price_long, "多单初损值：",round(g_stp_long, 5), "多单当前止损值：",round(g_stp_long, 5))
                if position.pos_short>0:
                    print("代码", symbol, "时间：", quote.datetime, "空单持仓量：",position.pos_short, "空单持仓均价：",position.open_price_short, "空单初损值：",round(g_stp_short, 5), "空单当前止损值",round(g_stp_short, 5))
                #循环变量自加
                loop = loop + 1
                #持仓发生变化，则交易次数加1
                g_trade_count += 1

            #根据行情发生变化，对仓单进行处理
            if api.is_changing(quote,["last_price", "bid_volume1", "ask_volume1"]):
                #如果空仓，初始化全局变量
                if position.pos_long==0:
                    g_flag_long=0
                    g_stp_long=0
                if position.pos_short==0:
                    g_flag_short=0
                    g_stp_short=0

                #止损均线下方不允许做多，上方不允许做空
                #多头平仓
                if position.pos_long>0 and klines.close.iloc[-2] < round(boll["mid"].iloc[-2],5): #and klines.close.iloc[-3] < round(boll["mid"].iloc[-3],2):  #quote.last_price<pre_boll_value :
                    #对上海交易所和原油单独处理，因为上海交易所和原油要同时用平今和平昨
                    if symbol.split(".")[0]=="SHFE" or symbol.split(".")[0]=="SHFE" or symbol.split(".")[0]=="SHFE":
                        #如果持有昨天的仓单，先平昨
                        if position.pos_long_his>0:
                            g_order_dcpz.append(api.insert_order(symbol=symbol, direction="SELL", offset="CLOSE", volume=position.pos_long_his, limit_price=quote.bid_price1-g_price_diff*2))
                        #如果当日有仓单，平今
                        if position.pos_long_today>0:
                            g_order_dcpj.append(api.insert_order(symbol=symbol, direction="SELL", offset="CLOSETODAY", volume=position.pos_long_today, limit_price=quote.bid_price1-g_price_diff*2))
                    else:
                        g_order_dc.append(api.insert_order(symbol=symbol, direction="SELL", offset="CLOSE", volume=position.pos_long, limit_price=quote.bid_price1-g_price_diff*2))
                    print(symbol+"  多头错单，挂空单平仓")

                #空头平仓
                if position.pos_short>0 and klines.close.iloc[-2] > round(boll["mid"].iloc[-2],5): # and klines.close.iloc[-3] > round(boll["mid"].iloc[-3],2):  #and quote.last_price>pre_boll_value:
                    #对上海交易所和原油单独处理，因为上海交易所和原油要同时用平今和平昨
                    if symbol.split(".")[0]=="SHFE" or symbol.split(".")[0]=="SHFE" or symbol.split(".")[0]=="SHFE":
                        #平昨
                        if position.pos_short_his>0:
                            g_order_kcpz.append(api.insert_order(symbol=symbol, direction="BUY", offset="CLOSE", volume=position.pos_short_his, limit_price=quote.ask_price1+g_price_diff*2))
                        #平今
                        if position.pos_short_today>0:
                            g_order_kcpj.append(api.insert_order(symbol=symbol, direction="BUY", offset="CLOSETODAY", volume=position.pos_short_today, limit_price=quote.ask_price1+g_price_diff*2))
                    else:
                        g_order_kc.append(api.insert_order(symbol=symbol, direction="BUY", offset="CLOSE", volume=position.pos_short, limit_price=quote.ask_price1+g_price_diff*2))
                    print(symbol+"  空头错单，挂多单平仓")

                #根据价格上下穿mid的情况，下多单或空单
                if True: #g_trade_count <= trade_count
                    
                    #如果金叉
                    if g_long_enabled and ((len(g_order_dk)>0 and g_order_dk[-1].status=="FINISHED" and g_order_dk[-1].volume_left==0) or len(g_order_dk)==0) and  position.pos_long < g_lots  and klines.close.iloc[-2] > round(boll["mid"].iloc[-2],5) and klines.close.iloc[-3] < round(boll["mid"].iloc[-3],5):  #position.pos_long<lots and
                        #做多前，如果持有空单，先平空，避免锁仓
                        if position.pos_short>0:
                            #对上海交易所和原油单独处理，因为上海交易所和原油要同时用平今和平昨
                            if symbol.split(".")[0]=="SHFE" or symbol.split(".")[0]=="SHFE" or symbol.split(".")[0]=="SHFE":
                                #平昨
                                if position.pos_short_his>0:
                                    g_order_kcpz.append(api.insert_order(symbol=symbol, direction="BUY", offset="CLOSE", volume=position.pos_short_his, limit_price=quote.ask_price1+g_price_diff*2))
                                #平今
                                if position.pos_short_today>0:
                                    g_order_kcpj.append(api.insert_order(symbol=symbol, direction="BUY", offset="CLOSETODAY", volume=position.pos_short_today, limit_price=quote.ask_price1+g_price_diff*2))
                            else:
                                g_order_kc.append(api.insert_order(symbol=symbol, direction="BUY", offset="CLOSE", volume=position.pos_short, limit_price=quote.ask_price1+g_price_diff*2))
                            print(symbol+"  下多单前，平空仓  ",position.pos_short)
                        #如果没有空单，直接做多
                        if position.pos_short==0:
                            g_open_price_long=quote.ask_price1+g_price_diff
                            g_order_dk.append(api.insert_order(symbol=symbol, direction="BUY", offset="OPEN", volume=abs(g_lots-position.pos_long), limit_price=g_open_price_long))
                            g_stp_long=g_open_price_long-g_stp_diff
                            g_flag_long=0
                            print(symbol + "  金叉挂多单", g_lots-position.pos_long,"  止损价：  ",g_stp_long)
                   
                    #如果死叉
                    if g_short_enabled and ((len(g_order_kk)>0 and g_order_kk[-1].status=="FINISHED" and g_order_kk[-1].volume_left==0) or len(g_order_kk)==0) and position.pos_short < g_lots and klines.close.iloc[-2] < round(boll["mid"].iloc[-2],5) and klines.close.iloc[-3] > round(boll["mid"].iloc[-3],5):  #position.pos_short<lots and
                        #如果持有多单先平多单，避免锁仓
                        if position.pos_long>0:
                            #对上海交易所和原油单独处理，因为上海交易所和原油要同时用平今和平昨
                            if symbol.split(".")[0]=="SHFE" or symbol.split(".")[0]=="SHFE" or symbol.split(".")[0]=="SHFE":
                                #如果持有昨天的仓单，先平昨
                                if position.pos_long_his>0:
                                    g_order_dcpz.append(api.insert_order(symbol=symbol, direction="SELL", offset="CLOSE", volume=position.pos_long_his, limit_price=quote.bid_price1-g_price_diff*2))
                                #如果当日有仓单，平今
                                if position.pos_long_today>0:
                                    g_order_dcpj.append(api.insert_order(symbol=symbol, direction="SELL", offset="CLOSETODAY", volume=position.pos_long_today, limit_price=quote.bid_price1-g_price_diff*2))
                            else:
                                g_order_dc.append(api.insert_order(symbol=symbol, direction="SELL", offset="CLOSE", volume=position.pos_long, limit_price=quote.bid_price1-g_price_diff*2))
                            print(symbol+"  下空单前，平多仓  ",position.pos_long)
                        #如果没有多单，直接做空
                        if position.pos_long==0:
                            g_open_price_short=quote.bid_price1-g_price_diff
                            g_order_kk.append(api.insert_order(symbol=symbol, direction="SELL", offset="OPEN", volume=abs(g_lots-position.pos_short), limit_price=g_open_price_short))
                            g_stp_short=g_open_price_short+g_stp_diff
                            g_flag_short=0
                            print(symbol + "  死叉挂空单", g_lots-position.pos_short,"  止损价：  ", g_stp_short)
                    
                #多单设止损及平保
                if position.pos_long > 0 and position.open_price_long>0: #position.open_price_long != None:
                    if g_flag_long < 1:
                        g_stp_long = position.open_price_long - g_stp_diff
                    if (g_flag_long < 2 and quote.bid_price1 > (position.open_price_long + g_stp_diff)) :
                        g_stp_long = position.open_price_long + g_pb_diff
                        g_flag_long = 1
                    if  g_flag_long < 3 and pre_boll_value > (position.open_price_long + g_pb_diff):
                        g_stp_long = pre_boll_value
                        g_flag_long = 2
                    #达到止损条件、止损平仓
                    # print("------------------调试----------------------")
                    # print("g_flag_long",g_flag_long)
                    # print("g_stp_diff",g_stp_diff)
                    # print("quote.ask_price1:",quote.ask_price1)
                    # print("position.open_price_long",position.open_price_long)
                    # print("pre_boll_value:",pre_boll_value)
                    # print("g_stp_long:",g_stp_long)
                    # print("------------------调试----------------------")
                    if quote.ask_price1 < g_stp_long:
                        #对上海交易所和原油单独处理，因为上海交易所和原油要同时用平今和平昨
                        if symbol.split(".")[0]=="SHFE" or symbol.split(".")[0]=="INE" or symbol.split(".")[0]=="SHFE":
                            #平昨
                            if position.pos_short_his>0:
                                g_order_dspz.append(api.insert_order(symbol=symbol, direction="SELL", offset="CLOSE", volume=position.pos_long_his, limit_price=quote.bid_price1-g_price_diff*2))
                            #平今
                            if position.pos_short_today>0:
                                g_order_dspj.append(api.insert_order(symbol=symbol, direction="SELL", offset="CLOSETODAY", volume=position.pos_long_today, limit_price=quote.bid_price1-g_price_diff*2))
                        else:
                            g_order_ds.append(api.insert_order(symbol=symbol, direction="SELL", offset="CLOSE", volume=position.pos_long, limit_price=quote.bid_price1-g_price_diff*2))
                        print(symbol + "  止损平多单 ",position.pos_long," 止损价： ",g_stp_long," g_flag_long: ",g_flag_long)

                #空单设止损及平保
                if position.pos_short > 0 and position.open_price_short>0:
                    if g_flag_short < 1:
                        g_stp_short = position.open_price_short + g_stp_diff
                    if (g_flag_short < 2 and quote.ask_price1 < position.open_price_short - g_stp_diff):
                        g_stp_short = position.open_price_short - g_pb_diff
                        g_flag_short = 1
                    if (g_flag_short < 3 and pre_boll_value <position.open_price_short - g_pb_diff):
                        g_stp_short = pre_boll_value
                        g_flag_short = 2
                    #达到止损条件、止损平仓
                    # print("------------------调试----------------------")
                    # print("g_flag_short",g_flag_short)
                    # print("g_stp_diff",g_stp_diff)
                    # print("quote.bid_price1:",quote.bid_price1)
                    # print("position.open_price_short",position.open_price_short)
                    # print("pre_boll_value:",pre_boll_value)
                    # print("g_stp_short:",g_stp_short)
                    # print("------------------调试----------------------")
                    if quote.bid_price1 > g_stp_short:
                        #对上海交易所和原油单独处理，因为上海交易所和原油要同时用平今和平昨
                        if symbol.split(".")[0]=="SHFE" or symbol.split(".")[0]=="INE" or symbol.split(".")[0]=="SHFE":
                            #平昨
                            if position.pos_short_his>0:
                                g_order_kspz.append(api.insert_order(symbol=symbol, direction="BUY", offset="CLOSE", volume=position.pos_short_his, limit_price=quote.ask_price1+g_price_diff*2))
                            #平今
                            if position.pos_short_today>0:
                                g_order_kspj.append(api.insert_order(symbol=symbol, direction="BUY", offset="CLOSETODAY", volume=position.pos_short_today, limit_price=quote.ask_price1+g_price_diff*2))
                        else:
                            g_order_ks.append(api.insert_order(symbol=symbol, direction="BUY", offset="CLOSE", volume=position.pos_short, limit_price=quote.ask_price1+g_price_diff*2))
                        print(symbol + "  止损平空单 ",position.pos_short," 止损价： ",g_stp_short," g_flag_short ",g_flag_short)
                #主图上画出止损线
                klines["boll_stp"] = boll["mid"]
        except Exception as e:
            raise e

    #关闭实例，释放资源
    api.close()


#---------------------------------其他需要用到的函数---------------------------------
#发送Email给指定邮箱，监控程序运行状态
def send_mail_accinfo():
    # 创建API实例
    acc_info = TqApi(TqAccount(cp_broker_id, cp_account_id,cp_password))
    # 获取账户信息
    account = acc_info.get_account()
    msg = u"今日账户  浮动盈亏：" + str(account.float_profit)+"  平仓盈亏："+str(account.close_profit)
    send_mail(msg)
    #关闭api
    acc_info.close()


#终端输出账户信息，用线程调用，每1分钟输出一次
def print_accinfo():
    # 创建API实例
    acc_info = TqApi(TqAccount(cp_broker_id, cp_account_id,cp_password))
    # 获取账户信息
    account = acc_info.get_account()
    msg = u"*** 今日账户信息 ***  持仓盈亏：" + str(account.float_profit)+"  平仓盈亏："+str(account.close_profit)
    print(msg)
    #关闭api
    acc_info.close()

#将成交记录，录入数据库
def insert_orders_table(symbol,direction,offset,lots,price,dt,profit,note):
    #print("找到数据库录入函数")
    try:
        mydt=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
        #dt=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) #因为insert_date_time，参数传递过来的时间有错，所以用这个，这两个时间实际也是一样的
        #fdt=int(dt.strip("0"))+8*60*60
        #print(dt.strip("0"))
        #dt=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(fdt))
        #print(dt)
        dt=mydt
        list=[symbol,direction,offset,lots,price,dt,profit,note,mydt]
        str_list=[str(x) for x in list]
        print(str_list)
        conn = sqlite3.connect(r"data.db")
        print("conn",conn)
        c = conn.cursor()
        #e.execute('''INSERT INTO orders(id,symbol,direction,offset,lots,price,dt,profit,note) VALUES(NULL,?,?,?,?,?,?,?,?)''',str_list)
        sql="INSERT INTO orders VALUES(NULL,?,?,?,?,?,?,?,?,?)"
        c.execute(sql,str_list)
        conn.commit()
        c.close()
        conn.close()
        print(symbol+"  成交记录，已录入数据库！")
    except Exception as e:
        #raise e
        pass


#调度函数，定时发送邮件
def apscheduler_send_mail():
    scheduler = BackgroundScheduler()
    scheduler.add_job(send_mail_accinfo, 'cron', hour=8, minute=55)
    scheduler.add_job(send_mail_accinfo, 'cron', hour=15, minute=5)
    scheduler.add_job(send_mail_accinfo, 'cron', hour=20, minute=55)
    scheduler.add_job(send_mail_accinfo, 'cron', hour=23, minute=5)
    #测试
    scheduler.add_job(send_mail_accinfo, 'cron', hour=14, minute=18)
    scheduler.start()


#将账户信息存入日志
def write_log(log_time,log_info):
    if not os.path.exists(os.getcwd() + "\\logs"):
        os.mkdir(os.getcwd() + "\\logs")
    f_name = time.strftime("%Y-%m-%d", time.localtime())
    f = open(os.getcwd() + "\\logs\\" + f_name + ".txt","a",encoding="utf-8")
    f.write(str(log_time))
    f.write(str(log_info) + "\n")
    f.close()